package com.vr.xxaiagent.controller;

import com.vr.xxaiagent.agent.XxManus;
import com.vr.xxaiagent.app.LoveApp;
import io.swagger.v3.oas.annotations.Operation;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * AI 控制器
 *
 * @author hzh
 * @date 2025/06/08
 */
@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
public class AiController {

    private final LoveApp loveApp;
    private final ToolCallback[] allTools;
    private final ChatModel dashscopeChatModel;

    @GetMapping("/love-app/chat/sync")
    @Operation(description = "用同步的方式输出")
    public String doChatWithLoveAppSync(String message, String chatId) {
        return loveApp.doChat(message, chatId);
    }

    @GetMapping(value = "/love-app/chat/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @Operation(description = "用基于sse流式的方式输出")
    public Flux<String> doChatWithLoveAppSse(String message, String chatId) {
        return loveApp.doChatByStream(message, chatId);
    }

    @GetMapping(value = "/love-app/chat/sse2")
    @Operation(description = "用基于sse流式的方式2输出")
    public Flux<ServerSentEvent<String>> doChatWithLoveAppSse2(String message, String chatId) {
        return loveApp.doChatByStream(message, chatId)
                .map(data -> ServerSentEvent.builder(data).build());
    }

    @GetMapping(value = "/love-app/chat/sse/emitter")
    @Operation(description = "用基于sse流式中的emitter的方式输出")
    public SseEmitter doChatWithLoveAppSseEmitter(String message, String chatId) {
        // 创建一个较长时间的SseEmitter，用于保持长连接,3分钟超时
        SseEmitter emitter = new SseEmitter(1000 * 60 * 3L);
        // 获取Flux数据流,并订阅
        loveApp.doChatByStream(message, chatId)
                .subscribe(chunk -> {
                            // 当有数据片时触发
                            try {
                                emitter.send(chunk);
                            } catch (IOException e) {
                                emitter.completeWithError(e);
                            }
                        },
                        // 异常时触发
                        emitter::completeWithError,
                        // 完成时触发
                        emitter::complete);
        // 返回emitter
        return emitter;
    }

    @GetMapping(value = "/manus/chat")
    @Operation(description = "流式方式调用Manus")
    public SseEmitter doChatWithManus(String message, String chatId) {
        XxManus xxManus = new XxManus(allTools, dashscopeChatModel);
        return xxManus.runStream(message);
    }

    @GetMapping(value = "/chat/list")
    @Operation(description = "通过会话id,获取消息列表")
    public Map<String, List<String>> getMessageList(String chatId) {
        return loveApp.getMessageList(chatId);
    }
};
